package cn.itcast.bos.web.base.action;

import cn.itcast.bos.service.base.BaseService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

/**
 * 代码重构优化
 * 运用代理设置模式
 * 抽象类实现Jpa标准提供变量和实现供被继承类复用
 */
public abstract class BaseAction<T,S extends BaseService<T>> extends ActionSupport implements ModelDriven<T>{

    //模型驱动 只能被子类继承
    protected T model;

    @Autowired
    S service;

    @Override
    public T getModel() {
        return model;
    }


    //模型驱动,接受分页数据
    protected int page;
    protected int rows;
    //提供对应的接受set方法
    public void setPage(int page) {
        this.page = page;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }
    //接受分页数据压入值栈
    protected void pushPageDataToValueStack(Page<T> pageData){
        Map<String,Object> result = new HashMap<>();
        result.put("total",pageData.getNumberOfElements());
        result.put("rows",pageData.getContent());
        ActionContext.getContext().getValueStack().push(result);
    }

    //完成model的实例化
    public BaseAction(){
        //构造子类Action对象,获得继承父类型的泛型
        //继承父类时指定泛型的类型 extends BaseAction<Area>()
        //这里this获得的是继承BaseAction类的对象,所以这里获取的是BaseAction的泛型
        Type genericSuperclass = this.getClass().getGenericSuperclass();
        //获取参数化类型 如ModelDriven<T>
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        //获取实际参数类型
        Class<T> modelClass = (Class<T>) parameterizedType.getActualTypeArguments()[0];

        try {
            model = modelClass.newInstance();
        } catch (InstantiationException|IllegalAccessException e) {
            e.printStackTrace();
        }
    }


}
